package com.ruoyi.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.mapper.*;
import com.ruoyi.business.service.*;
import com.ruoyi.common.core.domain.dto.PayoutsDTO;
import com.ruoyi.common.core.domain.dto.RefundDTO;
import com.ruoyi.common.core.domain.dto.WsdMealRefundsDTO;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.common.core.domain.vo.FuiouNotifyVO;
import com.ruoyi.common.core.domain.vo.RechargeRefundVO;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.date.DateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;

/**
 * 请假审批记录Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-16
 */
@Slf4j
@Service
public class WsdLeaveRecordsServiceImpl  extends ServiceImpl<WsdLeaveRecordsMapper, WsdLeaveRecords> implements IWsdLeaveRecordsService
{
    @Autowired
    private WsdLeaveRecordsMapper wsdLeaveRecordsMapper;
    @Autowired
    private WsdLeavesMapper wsdLeavesMapper;
    @Autowired
    private WsdMealRefundsMapper wsdMealRefundsMapper;

    @Autowired
    private WsdPaymentRecordsMapper wsdPaymentRecordsMapper;
    @Autowired
    private FuiouNotifyService fuiouNotifyService;
    @Autowired
    private IWsdLeavesService wsdLeavesService;
    @Autowired
    private IWsdRechargeRefundService wsdRechargeRefundService;
    @Autowired
    private WsdCanteenBalanceServiceImpl wsdCanteenBalanceService;
    @Autowired
    private WsdCanteenBalanceMapper wsdCanteenBalanceMapper;
    @Autowired
    private IRefundApprovalService refundApprovalService;
    @Autowired
    private IWsdUserAccountService wsdUserAccountService;
    /**
     * 查询请假审批记录
     *
     * @param id 请假审批记录主键
     * @return 请假审批记录
     */
    @Override
    public WsdLeaveRecords selectWsdLeaveRecordsById(Long id) {
        return wsdLeaveRecordsMapper.selectWsdLeaveRecordsById(id);
    }

    /**
     * 查询请假审批记录列表
     *
     * @param wsdLeaveRecords 请假审批记录
     * @return 请假审批记录
     */
    @Override
    public List<WsdLeaveRecords> selectWsdLeaveRecordsList(WsdLeaveRecords wsdLeaveRecords) {
        List<WsdLeaveRecords> wsdLeaveRecordsList = wsdLeaveRecordsMapper.selectWsdLeaveRecordsLists(wsdLeaveRecords);
        if (wsdLeaveRecordsList.size()>0){
            for (WsdLeaveRecords wsdLeaveRecord : wsdLeaveRecordsList){
                List<WsdMealRefundsDTO> list = wsdMealRefundsService.selectWsdMealRefundsListById(wsdLeaveRecord.getLeaveId());
                Integer lunch = 0;
                Integer dinner = 0;
                Integer breakfast = 0;
                if (list.size()>0){
                    for (WsdMealRefundsDTO wsdMealRefund : list){
                        wsdLeaveRecord.setRefundAmount( wsdLeaveRecord.getRefundAmount().add(wsdMealRefund.getRefundAmount() ) );
                        if (wsdMealRefund.getBreakfast()==1){
                            breakfast = breakfast + 1;
                        }
                        if (wsdMealRefund.getLunch()==1){
                            lunch = lunch + 1;
                        }
                        if (wsdMealRefund.getDinner()==1){
                            dinner = dinner + 1;
                        }
                    }
                }
                wsdLeaveRecord.setBreakfast( breakfast );
                wsdLeaveRecord.setLunch( lunch );
                wsdLeaveRecord.setDinner( dinner );
            }
        }
        return wsdLeaveRecordsList;
    }

    @Override
    public List<WsdLeaveRecords> wsdLeaveRecordsList(WsdLeaveRecords wsdLeaveRecords) {
        List<WsdLeaveRecords> wsdLeaveRecordsList = wsdLeaveRecordsMapper.wsdLeaveRecordsList(wsdLeaveRecords);
        return wsdLeaveRecordsList;
    }
    /**
     * 新增请假审批记录
     *
     * @param wsdLeaveRecords 请假审批记录
     * @return 结果
     */
    @Override
    public int insertWsdLeaveRecords(WsdLeaveRecords wsdLeaveRecords) {
        return wsdLeaveRecordsMapper.insertWsdLeaveRecords(wsdLeaveRecords);
    }

    /**
     * 修改请假审批记录
     *
     * @param wsdLeaveRecords 请假审批记录
     * @return 结果
     */
    @Override
    public int updateWsdLeaveRecords(WsdLeaveRecords wsdLeaveRecords) {
        return wsdLeaveRecordsMapper.updateWsdLeaveRecords(wsdLeaveRecords);
    }

    /**
     * 批量删除请假审批记录
     *
     * @param ids 需要删除的请假审批记录主键
     * @return 结果
     */
    @Override
    public int deleteWsdLeaveRecordsByIds(Long[] ids) {
        return wsdLeaveRecordsMapper.deleteWsdLeaveRecordsByIds(ids);
    }

    /**
     * 删除请假审批记录信息
     *
     * @param id 请假审批记录主键
     * @return 结果
     */
    @Override
    public int deleteWsdLeaveRecordsById(Long id) {
        return wsdLeaveRecordsMapper.deleteWsdLeaveRecordsById(id);
    }

    @Autowired
    private IWsdMealRefundsService wsdMealRefundsService;

    /**
     * 审批请假请求
     * @param wsdLeaveRecords
     * @return
     */
    @Override
    @Transactional
    public int appoveLeave(WsdLeaveRecords wsdLeaveRecords) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        WsdLeaves wsdLeaves = wsdLeavesMapper.selectWsdLeavesById(wsdLeaveRecords.getLeaveId());
        if (wsdLeaves == null){
            throw new RuntimeException("未找到对应的请假记录");
        }
//        LambdaQueryWrapper<WsdLeaveRecords> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(WsdLeaveRecords::getLeaveId,wsdLeaveRecords.getLeaveId());
//        WsdLeaveRecords wsdLeaveRecords1 = wsdLeaveRecordsMapper.selectList(wrapper).stream().findFirst().orElse(null);
//        if (wsdLeaveRecords1 == null){
//            throw new RuntimeException("未找到对应的提交请假审批记录");
//        }
        wsdLeaves.setStatus(wsdLeaveRecords.getSchoolApprovalStatus());
        wsdLeavesMapper.updateWsdLeaves(wsdLeaves);
        wsdLeaveRecords.setSchoolId(wsdLeaveRecords.getSchoolId());
        wsdLeaveRecords.setSchoolApprovalTime(new Date());
        wsdLeaveRecords.setSchoolApprovalStatus(wsdLeaveRecords.getSchoolApprovalStatus());
        if (wsdLeaveRecords.getSchoolApprovalStatus() == 1){
        //修改
        LambdaUpdateWrapper<WsdMealRefunds> wrapper1 = new LambdaUpdateWrapper<>();
        wrapper1.eq(WsdMealRefunds::getLeaveId,wsdLeaveRecords.getLeaveId());
        wrapper1.set(WsdMealRefunds::getStatus,2);
        wsdMealRefundsService.update(wrapper1);
        }
        else {
            //改为不同意退款
            LambdaUpdateWrapper<WsdMealRefunds> wrapper1 = new LambdaUpdateWrapper<>();
            wrapper1.eq(WsdMealRefunds::getLeaveId,wsdLeaveRecords.getLeaveId());
            wrapper1.set(WsdMealRefunds::getStatus,-1);
            wsdMealRefundsService.update(wrapper1);
        }
        wsdLeaveRecords.setSchoolApproverId( user.getUserId() );
        return wsdLeaveRecordsMapper.insertWsdLeaveRecords(wsdLeaveRecords);
    }

    @Override
    public int updateWsdMealRefunds(PayoutsDTO payoutsDTO) {
        //查出退餐数
        Integer breakfast = 0;
        Integer lunch = 0;
        Integer dinner = 0;
        //待退款的钱
        BigDecimal refundBreakfast = BigDecimal.ZERO;
        BigDecimal refundLunch = BigDecimal.ZERO;
        BigDecimal refundDinner = BigDecimal.ZERO;

        SysUser sysUser = SecurityUtils.getLoginUser().getUser();
        WsdMealRefunds wsdMealRefunds = new WsdMealRefunds();
        List<WsdMealRefundsDTO> list = wsdMealRefundsService.selectWsdMealRefundsListById( payoutsDTO.getLeaveId() );
        BigDecimal refundAmount = BigDecimal.ZERO;
        if (list.size() > 0) {
            for (WsdMealRefundsDTO wsdMealRefundsDTO : list) {
                wsdMealRefunds.setTransactionId( wsdMealRefundsDTO.getTransactionId() );
                refundAmount = refundAmount.add( wsdMealRefundsDTO.getRefundAmount() );
                //记录餐数
                if (wsdMealRefundsDTO.getBreakfast() == 1) {
                    breakfast = breakfast + 1;
                }
                if (wsdMealRefundsDTO.getLunch() == 1) {
                    lunch = lunch + 1;
                }
                if (wsdMealRefundsDTO.getDinner() == 1) {
                    dinner = dinner + 1;
                }
            }
            wsdMealRefunds.setRefundAmount( refundAmount );
        } else {
            log.info( "【财务审批操作】--未找到对应的退款记录，LeavedId:{}", payoutsDTO.getLeaveId() );
            throw new RuntimeException( "未找到对应的退款记录" );
        }
        if (payoutsDTO.getPayoutStatus() == 1) {//同意退款
            WsdLeaves getWsdLeaves = wsdLeavesService.selectWsdLeavesById( payoutsDTO.getLeaveId() );
            if (getWsdLeaves == null) {
                log.info( "【财务审批操作】--没有找到此请假条，LeavedId:{}", payoutsDTO.getLeaveId() );
                throw new RuntimeException( "没有找到此请假条" );
            }
            //查询余额表
            LambdaQueryWrapper<WsdCanteenBalance> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq( WsdCanteenBalance::getStudentId, getWsdLeaves.getStudentId() )
                    .eq( WsdCanteenBalance::getConfigId, getWsdLeaves.getConfigId() )
                    .eq( WsdCanteenBalance::getSchoolId, getWsdLeaves.getSchoolId() );
            // 查询学生在该学校的余额记录
            WsdCanteenBalance balance = wsdCanteenBalanceService.getOne( queryWrapper, false );
            if (balance == null) {
                log.info( "【财务审批操作】--未找到该学生订餐信息，StudentId={}", getWsdLeaves.getStudentId() );
                throw new RuntimeException( "未找到该学生订餐信息，请核实订餐情况！！" );
            }
            //TODO  没有TransactionId
            WsdPaymentRecords selectList = new WsdPaymentRecords();
            selectList.setStudentId( getWsdLeaves.getStudentId() );
            selectList.setConfigId( getWsdLeaves.getConfigId() );
            selectList.setIsPaid( true );
            List<WsdPaymentRecords> wsdPaymentRecordsList = wsdPaymentRecordsMapper.selectList( selectList );
            if (wsdPaymentRecordsList.isEmpty()) {
                log.info( "【财务审批操作】--未找到对应的充值记录，StudentId={},ConfigId={}", getWsdLeaves.getStudentId(), getWsdLeaves.getConfigId() );
                throw new RuntimeException( "未找到对应的充值记录，请联系管理员进行核实！！" );
            }
            //获取配置Config-----计算应退费用
            WsdRechargeRefund rechargeRefundVO = wsdRechargeRefundService.selectWsdRechargeRefundByConfigId( getWsdLeaves.getConfigId() );
            refundBreakfast = rechargeRefundVO.getBreakfastFee().multiply( BigDecimal.valueOf( breakfast ) );
            refundLunch = rechargeRefundVO.getLunchFee().multiply( BigDecimal.valueOf( lunch ) );
            refundDinner = rechargeRefundVO.getDinnerFee().multiply( BigDecimal.valueOf( dinner ) );
            BigDecimal balanceFeeA = BigDecimal.ZERO;
            BigDecimal balanceFeeB = BigDecimal.ZERO;
            BigDecimal balanceFeeC = BigDecimal.ZERO;
            BigDecimal balanceFeeD = BigDecimal.ZERO;
            for (WsdPaymentRecords wsdPaymentRecords : wsdPaymentRecordsList) {
                if (wsdPaymentRecords.getMealType() == 0){
                    balanceFeeA = balanceFeeA.add( wsdPaymentRecords.getBalanceFee() );
                }else if (wsdPaymentRecords.getMealType() == 1){
                    balanceFeeB = balanceFeeB.add( wsdPaymentRecords.getBalanceFee() );
                } else if (wsdPaymentRecords.getMealType() == 2) {
                    balanceFeeC = balanceFeeC.add( wsdPaymentRecords.getBalanceFee() );
                }else {
                    balanceFeeD = balanceFeeD.add( wsdPaymentRecords.getBalanceFee() );
                }
            }
            balanceFeeA = balanceFeeA.add( balanceFeeD );
            balanceFeeB = balanceFeeB.add( balanceFeeD );
            balanceFeeC = balanceFeeC.add( balanceFeeD );
            if (refundBreakfast.compareTo( balanceFeeA ) > 0) {
                log.info( "【财务审批操作】--账户可退余额不足LeavedId:{},refundAmount={}, balanceFee={}", getWsdLeaves.getId(), refundBreakfast, balanceFeeA );
                throw new RuntimeException( "退款失败，账户早餐可退余额不足！！" );
            }
            if (refundLunch.compareTo( balanceFeeB ) > 0) {
                log.info( "【财务审批操作】--账户可退余额不足LeavedId:{},refundAmount={}, balanceFee={}", getWsdLeaves.getId(), refundLunch, balanceFeeB );
                throw new RuntimeException( "退款失败，账户午餐可退余额不足！！" );
            }
            if (refundDinner.compareTo( balanceFeeC ) > 0) {
                log.info( "【财务审批操作】--账户可退余额不足LeavedId:{},refundAmount={}, balanceFee={}", getWsdLeaves.getId(), refundDinner, balanceFeeC );
                throw new RuntimeException( "退款失败，账户晚餐可退余额不足！！" );
            }
            BigDecimal refundAmount2 = refundAmount;
            for (WsdPaymentRecords wsdPaymentRecords : wsdPaymentRecordsList) {
                //待退款为0，直接退出循环
                if (refundAmount2.compareTo( BigDecimal.ZERO ) <= 0) {
                    break;
                }
                //余额是否大于0，否--跳过本个
                if (wsdPaymentRecords.getBalanceFee().compareTo( BigDecimal.ZERO ) > 0) {
                    FuiouNotifyVO fuiouNotifyVO = new FuiouNotifyVO();
                    //缴费类型
                    Integer mealType = wsdPaymentRecords.getMealType();
                    if (mealType == 0 && breakfast>0){
                        //早餐
                        //TODO 待退款小于余额
                        if (refundBreakfast.compareTo( wsdPaymentRecords.getBalanceFee() ) < 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundBreakfast );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceBreakfast( balance.getBalanceBreakfast().subtract( refundBreakfast ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundBreakfast,wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( refundBreakfast );
                                refundBreakfast = refundBreakfast.subtract( refundBreakfast );
                                breakfast = 0;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款等于余额
                        else if (refundBreakfast.compareTo( wsdPaymentRecords.getBalanceFee() ) == 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundBreakfast );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceBreakfast( balance.getBalanceBreakfast().subtract( refundBreakfast ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundBreakfast,wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( refundBreakfast );
                                refundBreakfast = refundBreakfast.subtract( refundBreakfast );
                                breakfast = 0;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款大于余额
                        else if (refundBreakfast.compareTo( wsdPaymentRecords.getBalanceFee() ) > 0) {
                            //先退部分
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, wsdPaymentRecords.getBalanceFee() );
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                //算出已退款的那部分餐数
                                BigDecimal returnadd = wsdPaymentRecords.getBalanceFee();
                                BigDecimal zaocan = rechargeRefundVO.getBreakfastFee();
                                Integer zaocanNum = 0;
                                while (returnadd.compareTo( BigDecimal.ZERO ) > 0) {
                                    if (returnadd.compareTo( zaocan ) >= 0 && zaocanNum < breakfast) {
                                        zaocanNum++;
                                        returnadd = returnadd.subtract( zaocan );
                                    }
                                    if (returnadd.compareTo( zaocan ) < 0 ) {//returnadd买不起餐
                                        break;
                                    }
                                    if (zaocanNum == breakfast ) {//餐数足够
                                        break;
                                    }
                                }
                                breakfast = breakfast - zaocanNum;
                                //修改余额表
                                balance.setBalanceBreakfast( balance.getBalanceBreakfast().subtract( wsdPaymentRecords.getBalanceFee() ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(wsdPaymentRecords.getBalanceFee(),wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( wsdPaymentRecords.getBalanceFee() );
                                refundBreakfast = refundBreakfast.subtract( wsdPaymentRecords.getBalanceFee() );
                                continue;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                        }
                    }
                    else if (mealType==1 && lunch>0) {
                        //午餐
                        //TODO 待退款小于余额
                        if (refundLunch.compareTo( wsdPaymentRecords.getBalanceFee() ) < 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundLunch );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceLunch( balance.getBalanceLunch().subtract( refundLunch ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundLunch,wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( refundLunch );
                                refundLunch = refundLunch.subtract( refundLunch );
                                lunch = 0;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款等于余额
                        else if (refundLunch.compareTo( wsdPaymentRecords.getBalanceFee() ) == 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundLunch );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceLunch( balance.getBalanceLunch().subtract( refundLunch ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundLunch,wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( refundLunch );
                                refundLunch = refundLunch.subtract( refundLunch );
                                lunch = 0;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款大于余额
                        else if (refundLunch.compareTo( wsdPaymentRecords.getBalanceFee() ) > 0) {
                            //先退部分
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, wsdPaymentRecords.getBalanceFee() );
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                //算出已退款的那部分餐数
                                BigDecimal returnadd = wsdPaymentRecords.getBalanceFee();
                                BigDecimal wucan = rechargeRefundVO.getLunchFee();
                                Integer wucanNum = 0;
                                while (returnadd.compareTo( BigDecimal.ZERO ) > 0) {
                                    if (returnadd.compareTo( wucan ) >= 0 && wucanNum < lunch) {
                                        wucanNum++;
                                        returnadd = returnadd.subtract( wucan );
                                    }
                                    if ( returnadd.compareTo( wucan ) < 0) {//returnadd买不起餐
                                        break;
                                    }
                                    if ( wucanNum == lunch) {//餐数足够
                                        break;
                                    }
                                }
                                lunch = lunch - wucanNum;

                                //修改余额表
                                balance.setBalanceLunch( balance.getBalanceLunch().subtract( wsdPaymentRecords.getBalanceFee() ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(wsdPaymentRecords.getBalanceFee(),wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( wsdPaymentRecords.getBalanceFee() );
                                refundLunch = refundLunch.subtract( wsdPaymentRecords.getBalanceFee() );
                                continue;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }

                        }

                    }
                    else if (mealType==2 &&dinner>0) {
                        //晚餐
                        //TODO 待退款小于余额
                        if (refundDinner.compareTo( wsdPaymentRecords.getBalanceFee() ) < 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundDinner );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceDinner( balance.getBalanceLunch().subtract( refundDinner ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundDinner,wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( refundDinner );
                                refundDinner = refundDinner.subtract( refundDinner );
                                dinner = 0;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款等于余额
                        else if (refundDinner.compareTo( wsdPaymentRecords.getBalanceFee() ) == 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundDinner );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceDinner( balance.getBalanceLunch().subtract( refundDinner ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundDinner,wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( refundDinner );
                                refundDinner = refundDinner.subtract( refundDinner );
                                dinner = 0;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款大于余额
                        else if (refundDinner.compareTo( wsdPaymentRecords.getBalanceFee() ) > 0) {
                            //先退部分
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, wsdPaymentRecords.getBalanceFee() );
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                //算出已退款的那部分餐数
                                BigDecimal returnadd = wsdPaymentRecords.getBalanceFee();
                                BigDecimal wucan = rechargeRefundVO.getLunchFee();
                                Integer wucanNum = 0;
                                while (returnadd.compareTo( BigDecimal.ZERO ) > 0) {
                                    if (returnadd.compareTo( wucan ) >= 0 && wucanNum < dinner) {
                                        wucanNum++;
                                        returnadd = returnadd.subtract( wucan );
                                    }
                                    if ( returnadd.compareTo( wucan ) < 0) {//returnadd买不起餐
                                        break;
                                    }
                                    if ( wucanNum == dinner) {//餐数足够
                                        break;
                                    }
                                }
                                dinner = dinner - wucanNum;

                                //修改余额表
                                balance.setBalanceDinner( balance.getBalanceDinner().subtract( wsdPaymentRecords.getBalanceFee() ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(wsdPaymentRecords.getBalanceFee(),wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( wsdPaymentRecords.getBalanceFee() );
                                refundDinner = refundDinner.subtract( wsdPaymentRecords.getBalanceFee() );
                                continue;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }

                        }

                    }
                    else  {
                        //总
                        //TODO 待退款小于余额
                        if (refundAmount2.compareTo( wsdPaymentRecords.getBalanceFee() ) < 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundAmount2 );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceBreakfast( balance.getBalanceBreakfast().subtract( refundBreakfast ) );
                                balance.setBalanceLunch( balance.getBalanceLunch().subtract( refundLunch ) );
                                balance.setBalanceDinner( balance.getBalanceDinner().subtract( refundDinner ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundAmount2,wsdPaymentRecords);
                                refundAmount2 = BigDecimal.ZERO;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款等于余额
                        else if (refundAmount2.compareTo( wsdPaymentRecords.getBalanceFee() ) == 0) {
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, refundAmount2 );
                            //退款结果
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                log.info( "【财务审核】退款状态:{},StudentId:{}", fuiouNotifyVO.getResult(), getWsdLeaves.getStudentId() );
                                //修改余额表
                                balance.setBalanceBreakfast( balance.getBalanceBreakfast().subtract( refundBreakfast ) );
                                balance.setBalanceLunch( balance.getBalanceLunch().subtract( refundLunch ) );
                                balance.setBalanceDinner( balance.getBalanceDinner().subtract( refundDinner ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundAmount2,wsdPaymentRecords);
                                refundAmount2 = BigDecimal.ZERO;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                            continue;
                        }

                        //TODO 待退款大于余额
                        else if (refundAmount2.compareTo( wsdPaymentRecords.getBalanceFee() ) > 0) {
                            //先退部分
                            fuiouNotifyVO = this.fuiouNotifyVO( wsdPaymentRecords, getWsdLeaves, wsdPaymentRecords.getBalanceFee() );
                            if ("退款成功".equals( fuiouNotifyVO.getResult() )) {
                                //算出已退款的那部分餐数
                                BigDecimal returnadd = wsdPaymentRecords.getBalanceFee();
                                BigDecimal zaocan = rechargeRefundVO.getBreakfastFee();
                                BigDecimal wucan = rechargeRefundVO.getLunchFee();
                                Integer zaocanNum = 0;
                                Integer wucanNum = 0;
                                Integer wancanNum = 0;
                                while (returnadd.compareTo( BigDecimal.ZERO ) > 0) {
                                    if (returnadd.compareTo( zaocan ) >= 0 && zaocanNum < breakfast) {
                                        zaocanNum++;
                                        returnadd = returnadd.subtract( zaocan );
                                    }
                                    if (returnadd.compareTo( wucan ) >= 0 && wucanNum < lunch) {
                                        wucanNum++;
                                        returnadd = returnadd.subtract( wucan );
                                    }
                                    if (returnadd.compareTo( zaocan ) < 0 && returnadd.compareTo( wucan ) < 0) {//returnadd买不起餐
                                        break;
                                    }
                                    if (zaocanNum == breakfast && wucanNum == lunch) {//餐数足够
                                        break;
                                    }
                                }
                                breakfast = breakfast - zaocanNum;
                                lunch = lunch - wucanNum;

                                //修改余额表
                                balance.setBalanceBreakfast( balance.getBalanceBreakfast().subtract( refundBreakfast ) );
                                balance.setBalanceLunch( balance.getBalanceLunch().subtract( refundLunch ) );
                                balance.setBalanceDinner( balance.getBalanceDinner().subtract( refundDinner ) );
                                wsdCanteenBalanceMapper.updateBalanceByMealTypeById( balance );
                                log.info( "更新余额成功,studentId{}", getWsdLeaves.getStudentId() );
                                //修改订单可退余额
                                this.updateWsdPaymentRecords(refundAmount2,wsdPaymentRecords);
                                refundAmount2 = refundAmount2.subtract( wsdPaymentRecords.getBalanceFee() );
                                continue;
                            } else {
                                log.info( "【财务审核】退款状态:{},退款refundOrderNo:{},StudentId:{}", fuiouNotifyVO.getResult(), fuiouNotifyVO.getOrderId(), getWsdLeaves.getStudentId() );
                                //throw new RuntimeException( fuiouNotifyVO.getResult() );
                                continue;
                            }
                        }
                    }
                }else {
                    continue;
                }
            }
            //修改餐费退款表状态
            for (WsdMealRefundsDTO wsdMealRefundsDTO : list) {
                WsdMealRefunds wsdMealRefunds2 = new WsdMealRefunds();
                wsdMealRefunds2.setMealRefundsId( wsdMealRefundsDTO.getMealRefundsId() );
                wsdMealRefunds2.setStatus( 1 );//退款状态：0=不同意退款, 1=同意退款
                wsdMealRefundsMapper.updateWsdMealRefunds( wsdMealRefunds2 );
            }
            //修改状态
            WsdLeaves wsdLeaves = new WsdLeaves();
            wsdLeaves.setId( payoutsDTO.getLeaveId() );
            wsdLeaves.setPayoutStatus( payoutsDTO.getPayoutStatus() );//退款状态：0=不同意退款, 1=同意退款
            if (payoutsDTO.getPayoutRemarks() != null && !"".equals( payoutsDTO.getPayoutRemarks() )) {
                wsdLeaves.setPayoutRemarks( payoutsDTO.getPayoutRemarks() );
            }
            wsdLeavesService.updateWsdLeaves( wsdLeaves );
            //审批记录
            RefundApproval refundApproval = new RefundApproval();
            refundApproval.setLeaveId( payoutsDTO.getLeaveId() );
            refundApproval.setSchoolId( getWsdLeaves.getSchoolId() );
            refundApproval.setRefundApprovalStatus( 1L );
            if (payoutsDTO.getPayoutRemarks()!=null&&!"".equals( payoutsDTO.getPayoutRemarks() )){
                refundApproval.setRefundComment( payoutsDTO.getPayoutRemarks() );
            }
            //审核人
            refundApproval.setApproverUserId( sysUser.getUserId() );
            refundApprovalService.insertRefundApproval(refundApproval);
            WsdLeaveRecords wsdLeaveRecords = new WsdLeaveRecords();
            wsdLeaveRecords.setLeaveId( payoutsDTO.getLeaveId() );
            wsdLeaveRecords.setSchoolId( sysUser.getSchoolId() );
            wsdLeaveRecords.setSchoolApproverId( sysUser.getUserId() );
            wsdLeaveRecords.setParentApprovalStatus( 1L );
            wsdLeaveRecords.setSchoolApprovalStatus( 1L );
            wsdLeaveRecords.setSchoolApprovalTime( new Date() );
            wsdLeaveRecords.setSchoolComment( payoutsDTO.getPayoutRemarks() );
            wsdLeaveRecordsMapper.insertWsdLeaveRecords( wsdLeaveRecords );
            return 1;
        } else {//不同意退款
            //修改请假记录状态
            WsdLeaves wsdLeaves = new WsdLeaves();
            wsdLeaves.setId( payoutsDTO.getLeaveId() );
            wsdLeaves.setPayoutStatus( payoutsDTO.getPayoutStatus() );//退款状态：0=不同意退款, 1=同意退款
            if (payoutsDTO.getPayoutRemarks() != null && !"".equals( payoutsDTO.getPayoutRemarks() )) {
                wsdLeaves.setPayoutRemarks( payoutsDTO.getPayoutRemarks() );
            }
            wsdLeavesService.updateWsdLeaves( wsdLeaves );
            //修改餐费退款表状态
            for (WsdMealRefundsDTO wsdMealRefundsDTO : list) {
                WsdMealRefunds wsdMealRefunds2 = new WsdMealRefunds();
                wsdMealRefunds2.setMealRefundsId( wsdMealRefundsDTO.getMealRefundsId() );
                wsdMealRefunds2.setStatus( 0 );
                wsdMealRefundsMapper.updateWsdMealRefunds( wsdMealRefunds2 );
            }
            //退款审批列表
            RefundApproval refundApproval = new RefundApproval();
            refundApproval.setLeaveId( payoutsDTO.getLeaveId() );
            refundApproval.setSchoolId( sysUser.getSchoolId() );
            refundApproval.setRefundApprovalStatus( 0L );
            if (payoutsDTO.getPayoutRemarks()!=null&&!"".equals( payoutsDTO.getPayoutRemarks() )){
                refundApproval.setRefundComment( payoutsDTO.getPayoutRemarks() );
            }
            //审核人
            refundApproval.setApproverUserId( sysUser.getUserId() );
            refundApprovalService.insertRefundApproval(refundApproval);
            WsdLeaveRecords wsdLeaveRecords = new WsdLeaveRecords();
            wsdLeaveRecords.setLeaveId( payoutsDTO.getLeaveId() );
            wsdLeaveRecords.setSchoolId( sysUser.getSchoolId() );
            wsdLeaveRecords.setSchoolApproverId( sysUser.getUserId() );
            wsdLeaveRecords.setParentApprovalStatus( 1L );
            wsdLeaveRecords.setSchoolApprovalStatus( 2L );
            wsdLeaveRecords.setSchoolApprovalTime( new Date() );
            wsdLeaveRecords.setSchoolComment( payoutsDTO.getPayoutRemarks() );
            wsdLeaveRecordsMapper.insertWsdLeaveRecords( wsdLeaveRecords );
            return 1;
        }

    }
    private FuiouNotifyVO fuiouNotifyVO(WsdPaymentRecords wsdPaymentRecords, WsdLeaves getWsdLeaves,BigDecimal refundAmount2) {
        FuiouNotifyVO fuiouNotifyVO = new FuiouNotifyVO();
        RefundDTO refundDTO = new RefundDTO();
        refundDTO.setRefundAmt( refundAmount2 );//退款金额
        refundDTO.setTransactionId( wsdPaymentRecords.getTransactionId() );
        refundDTO.setMealType( wsdPaymentRecords.getMealType() );
        if (wsdPaymentRecords.getRechargeType() == 2) {//代付接口
            WsdUserAccount wsdUserAccount = new WsdUserAccount();
            if (getWsdLeaves.getAccountId()!=null) {
                 wsdUserAccount = wsdUserAccountService.selectWsdUserAccountByAccountId( getWsdLeaves.getAccountId() );
            }else {
                WsdUserAccount wsdUserAccount1 = new WsdUserAccount();
                wsdUserAccount1.setUserId( getWsdLeaves.getParentId() );
                wsdUserAccount = wsdUserAccountService.selectWsdUserAccount( wsdUserAccount1 );
            }
            if (wsdUserAccount == null) {
                log.info( "【财务审批操作】--账户信息不存在，LeavedId:{}", getWsdLeaves.getId() );
                fuiouNotifyVO.setResult( "退款失败，账户信息不存在" );
                return fuiouNotifyVO;
            }
            fuiouNotifyVO = fuiouNotifyService.payment( refundDTO, getWsdLeaves, wsdUserAccount );
        } else {//订单接口
            //订单支付交易日
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyyMMdd" );
            String formattedDateTime = wsdPaymentRecords.getRechargeTime().format( formatter );
            refundDTO.setReservedOrigiDt( formattedDateTime );
            refundDTO.setMchntOrderNo( wsdPaymentRecords.getTransactionId() );
            fuiouNotifyVO = fuiouNotifyService.refund( refundDTO, getWsdLeaves );
        }
        return fuiouNotifyVO;
    }
    //修改订单
    public int updateWsdPaymentRecords(BigDecimal returnmoney,WsdPaymentRecords wsdPaymentRecords){
        WsdPaymentRecords wsdPaymentRecords1 = new WsdPaymentRecords();
        wsdPaymentRecords1.setPaymentId( wsdPaymentRecords.getPaymentId() );
        wsdPaymentRecords1.setBalanceFee( wsdPaymentRecords.getBalanceFee().subtract( returnmoney ) );
        return wsdPaymentRecordsMapper.updateWsdPaymentRecords(wsdPaymentRecords1);
    }
}
